Bitset in rust
- moved to notion https://choiwheatley.notion.site/Bitset-in-rust-56ebc5cb130a4fdfb7cdecf9f78b232e
- parent 0013 Rust π¦
λ¬μ€νΈλ‘ game of life ꡬννκΈ°λ₯Ό μ§ννλ©΄μ enum 벑ν°λ₯Ό μ΅μ ν ν μ μλ λ°©λ²μΌλ‘ μ΄μ°¨νΌ bool 벑ν°μΈ μ μ΄λ―λ‘ λΉνΈμ μ μ¬μ©νλ λ°©λ²μ΄ μ’κ² λ€κ³ νλ¨νμ¬ κ΅¬νμ μμνμλ€.
C++μμ λΉνΈμ μ λ§λ€μλ κΈ°μ΅μ΄ μμΌλ―λ‘ λ± λ κ°μ§λ§ κΈ°μ΅νλ©΄ λλ€.
bin_number = index / (size_of(element_type) * 8)
bit_number = index % (size_of(element_type) * 8)
λ νλΌλ©ν°λ₯Ό ꡬνλ ν¨μ bin_no
μ inner_idx
λ₯Ό μμ±νμλ€. μ΄κ±° κ·Όλ° λ¬μ€νΈμμ μΈλΌμΈ μ μ λͺ»νλ? => κ°μ μ μΌλ‘ μΈλΆμμ νΈμΆλμ§ μλ private ν¨μμ λν΄μ κ΅³μ΄ μΈλΌμΈ ν νμ μλ€.
use std::mem::size_of;
fn bin_no(idx: usize) -> usize {
idx / <usize>() * 8
}
fn inner_idx(idx: usize) -> usize {
idx % <usize>() * 8
}
Bitset
νμ
κ³Ό μμ±μλ₯Ό μ μν΄λ³΄μ. μ°λ¦¬κ° λ§λ€ λΉνΈμ
μ μ΄κΈ° ν¬κΈ°κ° κ³ μ λμ΄μλ€. μμ§μ λ°°μ΄ ν¬κΈ°λ₯Ό μ λ€λ¦νκ² λ§λλ λ°©λ²μ λͺ¨λ₯΄λ 벑ν°λ₯Ό μ°μ. generic array in rust
pub struct Bitset {
bits: Vec<usize>,
}
impl Bitset {
/// creates [false; size] like bitset
pub fn with_size(size: usize) -> Self {
let size = bin_no(size) + 1; // νΉμ λͺ¨λ₯΄λ μ¬μ λ‘κ²
let mut v = Vec::with_capacity(size); // size μλλλ€, capacity μ
λλ€.
v.resize(size, 0);
Bitset {bits: v}
}
/// indicesμ κ° μμλ€μ μΈλ±μ€κ° trueμΈ μ Bitsetλ₯Ό λ°ννλ€.
pub fn from_indices(indices: &[usize]) -> Self {
let size = bin_no(indices.len()) + 1;
let mut v = Vec::with_capacity(size);
v.resize(size, 0);
for i in indices.iter().cloned() {
*v.get_mut(bin_no(i)).expect("Index out of bounds") |= 1 << inner_idx(i);
}
Bitset { bits: v }
}
}
λ€μμ μΈλ±μ±μ νμ©νμ¬ get, setμ νλ λ©μλλ₯Ό μ μν΄λ³΄μ
impl Bitset {
pub fn get(&self, idx: usize) -> bool {
self.bits.get(bin_no(idx))
.expect("Index Out of Bounds") >> inner_idx(idx) & 0b01 == 1
}
pub fn set(&mut self, idx: usize) {
*self.bits.get_mut(bin_no(idx))
.expect("Index Out of Bounds") |= 1 << inner_idx(idx);
}
pub fn reset(&mut self, idx: usize) {
*self.bits.get_mut(bin_no(idx))
.expect("Index Out of Bounds") &= !(1 << inner_idx(idx));
}
pub fn set_to(&mut self, idx: usize, to: bool) {
if to {
self.set(idx);
} else {
self.reset(idx);
}
}
μλλ λΉνΈμ κ΄λ ¨ ν μ€νΈμ΄λ€. λ¬μ€νΈλ‘ game of life ꡬννκΈ° ν λ λλ²κΉ μ©μΌλ‘ κ°λ¨νκ² ν μ€νΈ μ½λλ₯Ό μμ±νλ€. μ΄λ λ¬μ€νΈ λͺ¨λ ꡬ쑰μ λν μ΄ν΄λ₯Ό λ€μΌλ‘ μ»μ΄κ°λ€.
- μ λ ν μ€νΈλ ν μ€νΈ νλ €λ λͺ¨λκ³Ό κ°μ νμΌ μμμ μννλ€.
- ν
μ€νΈ λͺ¨λνμΌ μμ
#[cfg(test)] mod tests{}
λΈλ μμμ ν μ€νΈ μ½λλ₯Ό μμ±νλ©΄ λλ€. -- μμ λͺ¨λμ λΆλͺ¨ λͺ¨λμ private μμλ€μ μμ λ‘κ² μ κ·Όν μ μλ€λ μ κΈ°μ΅νκ³ .
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bin_no() {
for i in 0..=128 {
assert_eq!(i / 32, bin_no(i), "i : {}", i);
}
}
#[test]
fn test_init() {
let bs = Bitset::with_size(32);
assert_eq!(2, bs.bits.len());
for i in 0..32 {
assert_eq!(false, bs.get(i), "in index {i}");
}
let bs = Bitset::with_size(128);
assert_eq!(5, bs.bits.len());
for i in 0..128 {
assert_eq!(false, bs.get(i), "in index {}", i);
}
}
#[test]
fn test_set_get() {
let size = 128;
let mut bs = Bitset::with_size(size);
for i in 0..size {
bs.set(i);
assert!(bs.get(i));
}
for i in (0..size).rev() {
bs.reset(i);
assert!(!bs.get(i));
}
}
}
fixedbitset crateλ₯Ό μ¬μ©νλ λ°©λ²λ μλ€. νμ§λ§ κ΅³μ΄?